package com.baishancloud.log.murloc.tools

import com.baishancloud.log.common.util.ArrayUtil
import com.baishancloud.log.murloc._
import org.apache.flink.api.java.utils.ParameterTool

import java.io.{BufferedReader, File, FileReader}
import java.{lang, util}

/**
 * 读取指定文件中的数据，然后将数据全都保存到内部的map中
 *
 * @author ziqiang.wang
 * @date 2021/12/21 12:35
 */
object IPInfo extends Serializable {

  // 保存指定文件中的数据
  private val ipDataS: util.TreeMap[Long, IPData] = new util.TreeMap[Long, IPData]
  // 将所有有序key提取出来，作为二分查找依据
  private var startArray: Array[lang.Long] = _

  def init(parameterTool: ParameterTool): Unit = {
    // 文件所在绝对路径
    val jarPath: String = new File("").getCanonicalPath
    val filePath: String = new File("").getCanonicalPath + File.separator + parameterTool.get(dbFilePath)
    println(s"jarPath: $jarPath, filePath: $filePath")

    //读取指定文件内容，将其转化为map存储
    val reader: BufferedReader = new BufferedReader(new FileReader(filePath))
    var temp: String = reader.readLine()
    while (temp != null) {
      //将文件中共的一行内容转化为ipData对象
      val splits: Array[String] = temp.split(" ")
      val ipData: IPData = IPData(
        splits(0).toLong,
        splits(1).toLong,
        IdMap.countryMap.getOrElse(splits(2), 0),
        IdMap.providerMap.getOrElse(splits(4), 0),
        IdMap.providerMap.getOrElse(splits(5).split("/")(0), 0)
      )
      ipDataS.put(ipData.start, ipData)
      temp = reader.readLine()
    }
    startArray = new Array[lang.Long](ipDataS.size())
    var index: Int = 0
    ipDataS.keySet().forEach(k => {
      startArray.update(index, lang.Long.valueOf(k))
      index += 1
    })
    println(s"ipDataS元素数量：${ipDataS.size()}, startArray元素数量：${startArray.length}")
  }


  /**
   * 根据给定的ip地址，从map（文件）中查找对应的数据对象
   *
   * @param ip 标准ip地址
   */
  def get(ip: String): Option[IPData] = get(ip2Long(ip))

  def get(ip: Long): Option[IPData] = {
    val index: Int = ArrayUtil.binarySearch(startArray, lang.Long.valueOf(ip), "[]")
    if (index == -1) {
      None
    } else {
      Option(ipDataS.get(startArray(index)))
    }
  }

  /**
   * 将ip地址转化为long数字
   */
  private def ip2Long(ip: String): Long = {
    val atoms: Array[Long] = ip.split("\\.").map(_.toLong)
    val result: Long = (3 to 0 by -1).foldLeft(0L) { (result, position) =>
      result | (atoms(3 - position) << position * 8)
    }
    result & 0xFFFFFFFF
  }

}

